import React from 'react';
import { connect } from 'react-redux';
import {Icon, Button, Input, Select, Tree, Popover, message, Checkbox} from 'antd';
import 'styles/permission-setting/role-menu-setting/role-menu-setting-new.scss';
import RSService from 'containers/permission-setting/role-menu-setting/role-menu-setting.service';
import { messages, trim, deepFullCopy } from 'share/common';
import RoleMenu from 'containers/permission-setting/components/role-menu';
import NestTableMenu from 'components/nest-table-menu';
const Option = Select.Option;
const Search = Input.Search;
const {TreeNode} = Tree;
import baseService from 'share/base.service';

class RoleMenuSettingNew extends React.Component {
  constructor (props) {
    super(props);
    this.state = {
      treeDataLoading: false,
      webMenuList: [],
      webMenuListCopy: [],
      appMenuList: [],
      appMenuListCopy: [],
      expandedKeysRole: [],
      autoExpandParentRole: true,
      selectedKeysRole: [],
      selectedNode: {},
      selectedRole: {},
      isEditing: false,
      editArr: [],
      selectedClient: 'empty',
      saveLoading: false,
      isSearching: false,
      searchValue: '',
    };
    this.appMenuOpened = false; // 控制app是否全部展开
    this.appMenuTree = [];
  }

  //角色被选择的回调
  itemSelect = (key, data) => {
    this.setState({
      selectedRole: data,
      autoExpandParentRole: true,
      selectedKeysRole: [],
      selectedNode: {},
      isEditing: false,
      editArr: [],
    }, () => {
      this.getRoleMenu();
    });
  };

  //角色被选择的回调
  getRoleMenu = () => {
    const {selectedRole, searchValue} = this.state;
    RSService.getRoleMenu(selectedRole.id)
      .then(res => {
        let webMenuList = res.data.web.children, appMenuList = res.data.app.children;
        this.setState({
          webMenuList,
          appMenuList,
        }, () => {
          if (searchValue) {
            this.filterRoleList(null, searchValue);
          }
        });
      }).catch(err => {

    });
  };

  onCheckedChange = (status, item, client) => {
    const {searchValue, appMenuList, appMenuListCopy, expandedKeysRole, webMenuList, webMenuListCopy} = this.state;
    let arr = this.state.editArr,
     checked = typeof status === 'boolean' ? status : false, connectKeys = [item.key], that = this,
     realChecked = checked,
     obj = {
      '8000': 'general-widget-module',
      '8100': 'function-widget-module',
      '8200': 'mine-widget-module',
    };
    if (!item.operationType) {
      item.operationType = 'RW';
    }
    item.checked = realChecked;
    if (item.subFunctions && item.subFunctions.length) {
      item.subFunctions.forEach(sub => {
        sub.checked = realChecked;
      });
    }
    arr = this.replaceOrPush(arr, item);
    let connect = item.relevanceDetails;
    let clientArr = ['web', 'app'];
    let flag = 0;

    for (let i = 0; i < 2; i++) {
      if (connect && connect[clientArr[i]] && connect[clientArr[i]].length) {
        connect[clientArr[i]].map(con => {
          if (con.key !== item.key) {
            con.checked = realChecked;
            connectKeys.push(con.key);
            flag = flag + 1;
            if (flag === 1 && !this._isShowLinkedToast) {
              this._isShowLinkedToast= true
              message.info(messages('basic-5.key28')/*关联功能已同步操作*/);
              setTimeout(()=>{
                this._isShowLinkedToast= false
              }, 3000);
            }
          }
        });
        if (clientArr[i] === 'app') {
          loop.call(this, 'app', searchValue ? appMenuListCopy : appMenuList);
          this.setState({
            appMenuList,
            appMenuListCopy,
          });
        }
        if (clientArr[i] === 'web') {
          loop.call(this, 'web', searchValue ? webMenuListCopy : webMenuList);
          this.setState({
            webMenuList,
            webMenuListCopy,
          });
        }
      }
    }

    function loop (subClient, list, parent) {
      list.forEach(app => {
        if (app.children) {
          loop.call(this, subClient, app.children, app);
        } else {
          if (app.resourceType === 'F' && (connectKeys.indexOf(app.key) !== -1)) {
            if(subClient === 'app'){
              if (!app.operationType) {
                app.operationType = 'RW';
              }
              app.checked = realChecked;
              arr = that.replaceOrPush(arr, app);
              if (parent) {
                expandedKeysRole.addIfNotExist(parent.key);
                expandedKeysRole.addIfNotExist(obj[parent.parentId]);
              }
              expandedKeysRole.addIfNotExist(app.key);
              if (app.parentMenu) {
                this.handleParentMenuStatus(realChecked, app);
              }
            } else {
              if(client === 'app'){
                this.webMenuRef.onAppReferenceChange(realChecked, app, app.key);
              }
            }
            
          }
        }
      });
    }

    this.setState({
      editArr: arr,
      expandedKeysRole,
      autoExpandParentRole: true,
    });
    if (client === 'app' && item.children) {
      this.handleChildrenMenuChanged(realChecked, item);
    }
  };
  // 处理子菜单的状态, 保持与父级菜单相同
  handleChildrenMenuChanged = (status, menu) => {
    menu && menu.children.forEach(item => {
      this.onCheckedChange(status, item, 'app');
    });
  };
  // 处理父级菜单的状态, 如果父级菜单的子菜单 有一个选中的，则其选中，否则显示为未选中
  handleParentMenuStatus = (status, menu) => {
    if (menu.parentMenu) {
      menu = menu.parentMenu;
      if (status) {
        menu.checked = true;
        this.handleParentMenuStatus(true, menu);
      } else {
        if (!menu.children.some(item => item.checked)) {
          menu.checked = false;
          this.handleParentMenuStatus(false, menu);
        }
      }
    }
  };

  renderTreeNode = (list, client, parentMenu) => {
    const {isEditing, searchValue} = this.state;
    return list && list.length ?
      list.map(item => {
        if (parentMenu && !item.parentMenu) {
          item.parentMenu = parentMenu;
        }
        let key = item.key;
        if (item.children && !this.appMenuTree.includes(key)) {
          this.appMenuTree.push(key);
        }
        return (
          <TreeNode
            switcherIcon={<Icon type="form"/>}
            key={item.key}
            dataRef={item}
            title={
              <span>
                <Checkbox
                  checked={item.checked}
                  onClick={(e) => {
                    this.onCheckedChange(!item.checked, item, client);
                  }}
                  key={item.key}
                  disabled={!isEditing}>
                  {renderName(item)}
                </Checkbox>
              </span>
            }>
            {item.children && this.renderTreeNode(item.children, client, item)}
          </TreeNode>
        );
      }) : <TreeNode
        key={'no-menu'}
        dataRef={list}
        title={
          <span>{messages('basic-5.key29')/*无相关菜单*/}</span>
        }/>;

    function renderName (item) {
      let obj = {
        'R': {title: messages('basic-5.key30')/*只读*/, icon: 'eye-o'},
        'RW': {title: messages('basic-5.key31')/*可操作*/, icon: 'edit'},
        'H': {title: messages('basic-5.key32')/*不可见*/, icon: 'eye-invisible'},
      };
      return (
        <span>
              {
                item.relevanceDetails &&
                <Popover content={
                  <div>
                    <div>{messages('basic-5.key33')/*此功能存在关联功能，将同步操作关联功能。*/}</div>
                    <div>{messages('basic-5.key34')/*网页端功能*/}：
                      {
                        (item.relevanceDetails['web'] || []).map((web, index1) => {
                          return (
                            <span style={{marginRight: 10}}>
                                {web.resourceName}{(index1 === item.relevanceDetails['web'].length - 1) ? '' : '，'}
                              </span>
                          );
                        })
                      }
                    </div>
                    <div>{messages('basic-5.key35')/*移动端功能*/}：
                      {
                        (item.relevanceDetails['app'] || []).map((app, index) => {
                          return (
                            <span style={{marginRight: 10}}>
                              {app.resourceName}{(index === item.relevanceDetails['app'].length - 1) ? '' : '，'}
                            </span>
                          );
                        })
                      }
                    </div>
                  </div>
                }>
                  <Icon type="link" style={{color: '#4B8DFE', fontSize: 15, fontWeight: 600}}/>
                </Popover>
              }
              <span style={{margin: '0 5px'}}>
                {
                  searchValue ?
                    <span style={{color: isEditing ? '#4E5b71' : (item.checked ? '#4E5b71' : '#B5C0CE')}}
                          dangerouslySetInnerHTML={{
                            __html:
                              item.resourceName.replace(new RegExp(`${searchValue.toLowerCase()}`, 'img'), function(arg1){
                               return `<span style='color: #4B8DFF'>${arg1}</span>`})
                          }}
                    />
                    : <span style={{color: isEditing ? '#4E5b71' : (item.checked ? '#4E5b71' : '#B5C0CE')}}>
                        {item.resourceName}
                      </span>
                }
              </span>
          {
            item.appRemark &&
            <Popover content={item.appRemark}><Icon type="info-circle-o"/></Popover>
          }
          {
            item.operationType && client === 'web' &&
            <Popover content={obj[item.operationType].title}><Icon type={obj[item.operationType].icon}/></Popover>
          }
            </span>
      );
    }
  };

  //展开当前角色
  onExpandRole = (expandedKeys) => {
    this.setState({
      expandedKeysRole: expandedKeys,
      autoExpandParentRole: false,
    });
  };
  //选择功能菜单执行回调
  onSelectRole = (selectedKeys, info, client) => {
    let dataRef = info.node.props.dataRef;
    this.setState({
      selectedKeysRole: selectedKeys,
      selectedNode: dataRef,
      selectedClient: client,
    }, () => {
    });
  };

  cancelEdit = () => {
    this.webMenuRef.cancelOperationedMenu();
    this.setState({
      isEditing: false,
      editArr: [],
      selectedKeysRole: [],
      selectedNode: {},
      selectedClient: 'empty',
    }, () => {
      this.getRoleMenu();
    });
  };

  handleSave = () => {
    const {selectedRole, editArr} = this.state;
    this.setState({
      saveLoading: true
    });

    function loopDelPrentMenu (menu, value) {
      return menu && menu.map(item => {
        if (item.parentMenu) {
          item.parentMenu = value;
        }
        if (item.children) {
          item.children = loopDelPrentMenu(item.children, value);
        }
        return item;
      });
    }

    loopDelPrentMenu(editArr, true);

    let webOperationedMenu = this.webMenuRef.saveOperationedMenu();
    webOperationedMenu.forEach(menu => {
      menu.children = [];
      menu.subFunctions = [];
    });
    let editedMenu = editArr.concat(webOperationedMenu);
    RSService.editRoleMenu(selectedRole.id, editedMenu)
      .then(res => {
        this.setState({
          saveLoading: false
        });
        this.cancelEdit();
        baseService.judgeIfHasAdminHome()
          .then(res =>{

        }).catch(err => {

        })
      }).catch(err => {
      loopDelPrentMenu(editArr, null);
      this.setState({
        saveLoading: false
      });
    });
  };

  handleTabPermissionChange = (value, node, blind) => {
    const {editArr, selectedNode} = this.state;
    let result = node;
    if (blind) {
      selectedNode.subFunctions.map(item => {
        if (item.key === node.key) {
          item.operationType = value;
        }
      });
      result = selectedNode;
    } else {
      node.operationType = value;
    }
    let arr = this.replaceOrPush(editArr, result);
    this.setState({
      editArr: arr,
    });
  };

  renderOperationSelect = (selectedNode, blind) => {
    const {isEditing} = this.state;
    return (
      <div>
        {blind && <div className="standard-divider-title">{selectedNode.resourceName}</div>}
        <Select
          style={{width: 200, margin: '10px 0'}}
          disabled={!isEditing || (selectedNode.defaultReadable + '') === '0'}
          value={selectedNode.operationType || 'RW'}
          placeholder={messages('common.select')/*请选择*/}
          onChange={(value) => this.handleTabPermissionChange(value, selectedNode, blind)}>
          <Option value="RW">{messages('basic-5.key31')/*可操作*/}</Option>
          <Option value="R">{messages('basic-5.key30')/*只读*/}</Option>
          {
            blind &&
            <Option value="H">{messages('basic-5.key32')/*不可见*/}</Option>
          }
        </Select>
      </div>
    );
  };
  onSearchKeyDown = (e) => {
    let keyCode = e.keyCode;
    if (keyCode === 13) {
      let value = e.target && trim(e.target.value);
      this.setState({
        searchValue: value
      }, ()=>{
        this.filterRoleList();
      })
    }
  };
  filterRoleList = () => {
    if (!this.state.searchValue) return;
    const {webMenuList, appMenuList, expandedKeysRole, searchValue} = this.state;
    // let webMenuListCopy = handleChildren(webMenuList);
    let webMenuListCopy= handleWebChildren(webMenuList, 0)
    console.log('webMenuListCopy', webMenuListCopy)
    let appMenuListCopy = handleChildren(appMenuList);
    this.setState({
      webMenuListCopy,
      appMenuListCopy,
      isSearching: true,
      expandedKeysRole,
      autoExpandParentRole: true,
    });

    function handleChildren (arr) {
      let list = deepFullCopy(arr);
      return (
        list.filter(item => {
          if (item.children && item.children.length) {
            let arr = handleChildren(item.children);
            if (arr && arr.length) {
              item.children = arr;
              expandedKeysRole.push(item.key);
              return item;
            } else {
              if ((item.resourceType === 'F' || item.resourceType === 'C' || item.resourceType === 'M')
                && item.resourceName.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1) {
                expandedKeysRole.push(item.key);
                return item;
              }
            }
          } else {
            if ((item.resourceType === 'F' || item.resourceType === 'C' || item.resourceType === 'M')
              && item.resourceName.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1) {
              expandedKeysRole.push(item.key);
              return item;
            }
          }
        })
      );
    }

    function handleWebChildren (arr, level) {
      let list = arr
      if(level === 0){
        list = deepFullCopy(arr);
      }
      return list.filter(item => {
        if (item.children && item.children.length) {
          let matchedChildren = handleWebChildren(item.children, level + 1);
          if (matchedChildren.length != 0 || item.resourceName.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1) {
            // if(level === 0){
            //   item.children= matchedChildren
            // }
            item.matched= true
            return item
          }

        } else {
          if ((item.resourceType === 'F' || item.resourceType === 'C' || item.resourceType === 'M')
            && item.resourceName.toLowerCase().indexOf(searchValue.toLowerCase()) !== -1) {
            item.matched = true;
            return item
          }
        }
      })
    }
  };
  //搜索当前角色菜单
  setSearchedValue = (e, target) => {
    e.persist();
    if(this.timer){
      clearTimeout(this.timer)
    }
    this.timer= setTimeout(()=>{
      let value = target || trim(e.target.value);
      console.log('setSearchedValue', value);
      this.timer= null
      if (!value) {
        this.setState({
          webMenuListCopy: [],
          appMenuListCopy: [],
          expandedKeysRole: [],
          isSearching: false,
          searchValue: '',
        });
        return;
      }
      this.setState({
        searchValue: value,
      });
    }, 300)
  };

  editRole = () => {
    const {selectedRole} = this.state;
    this.roleMenuRef.showModalRole(selectedRole, true);
  };

  replaceOrPush = (list, target) => {
    let len = list.length, index = null;
    for (let i = 0; i < len; i++) {
      if (list[i].key === target.key) {
        index = i;
        break;
      }
    }
    if (index !== null) {
      list.splice(index, 1, target);
    } else {
      list.push(target);
    }
    return list;
  };

  onAppMenuToggle = (e) => {
    let status = !this.appMenuOpened;
    this.appMenuOpened = status;
    if (status) {
      this.setState({
        expandedKeysRole: this.appMenuTree
      });
    } else {
      this.setState({
        expandedKeysRole: []
      });
    }

    console.log('onAppMenuToggle', this.appMenuOpened, this.appMenuTree);
  };

  render () {
    const {
      treeDataLoading, expandedKeysRole, autoExpandParentRole, selectedKeysRole, appMenuList, webMenuList, selectedRole,
      isEditing, selectedClient, selectedNode, saveLoading, webMenuListCopy, appMenuListCopy, searchValue, isSearching
    } = this.state;
    let text = {
      'empty': messages('basic-5.key36')/*请选择菜单进行操作*/,
      'web': messages('basic-5.key37')/*网页端功能设置*/,
      'app': messages('basic-5.key38')/*移动端功能设置*/,
    };
    return (
      <div className="role-menu-setting-wrap">
        <div className='left-area'>
          <RoleMenu
            isShowEdit={false}
            isShowAdd={true}
            onRef={(ref) => this.roleMenuRef = ref}
            menuLoading={treeDataLoading}
            onSelect={this.itemSelect}
            onEdit={this.editRole}>
          </RoleMenu>
        </div>
        <div className="right-area">
          <div className="right-area-menu-tree">
            <div className={'role-menu-info'}>
              <div className={'role-title-content'}>
                 <span className="standard-divider-title">
                  {messages('basic-5.key39')/*角色菜单*/}
                </span>
                <Popover content={messages('basic-5.key40')/*如果添加的一级菜单没有二级菜单，一级菜单将不显示*/}>
                  &nbsp;<Icon type="info-circle-o"/>
                </Popover>
                {
                  isEditing ?
                    <span>
                    <Button type="primary" onClick={this.handleSave} style={{marginLeft: 15}}
                            loading={saveLoading}>
                      {messages('common.save')/*保存*/}
                    </Button>
                    <Button onClick={this.cancelEdit}
                            style={{marginLeft: 15}}>{messages('common.cancel')/*取消*/}</Button>
                  </span>
                    :
                    <Button type="primary"
                            onClick={() => {
                              this.setState({isEditing: true});
                            }}
                            style={{marginLeft: 15}}>
                      {messages('basic-5.key41')/*编辑菜单*/}
                    </Button>
                }
              </div>

              <Search
                className={'search-wrapper'}
                onKeyDown={e => {
                  this.onSearchKeyDown(e);
                }}
                placeholder={messages('basic-5.key42')/*搜索网页端/移动端功能*/}
                onChange={this.setSearchedValue}
                style={{width: 250, float: 'right'}}
                enterButton={
                  <div className={'btn-popover-wrapper'}>
                    <Popover content={messages('basic-5.key43')/*\"回车\"可直接搜索*/}>
                      <div className={'btn-popover-content'}>
                        <i className="anticon anticon-search"></i>
                      </div>
                    </Popover>
                  </div>
                  }
                onSearch={this.filterRoleList}
              />

            </div>
            <div className="menu-list-area">
              <div className="menu-list-area-search">
                <div className="web-menu-list-area">
                  <div className="standard-divider-title web-menu-list-title">
                    <span className="img-wrapper">
                      <Icon type="desktop"></Icon>
                    </span>
                    {messages('basic-5.key34')/*网页端功能*/}
                  </div>
                  <NestTableMenu
                    height={'80vh'}
                    width={'620px'}
                    onRef={(context) => this.webMenuRef = context}
                    dataSource={searchValue && isSearching ? webMenuListCopy : webMenuList}
                    isEdit={isEditing}
                    keyWord={searchValue}
                    selectedRole={selectedRole}
                    onMenuChanged={(e, item) => this.onCheckedChange(e, item, 'web')}
                  />
                </div>
                <div className="app-menu-list-area" style={{display: 'block'}}>
                  <div className="standard-divider-title app-menu-list-title">
                    <span className="img-wrapper">
                      <Icon type="mobile"></Icon>
                    </span>
                    {messages('basic-5.key35')/*移动端功能*/}
                  </div>
                  <div className={'app-menu-content'}>
                    <div className="app-menu-title">
                    <span
                      className={`icon icon-cursor`}
                      onClick={(e) => this.onAppMenuToggle(e)}>
                      {this.appMenuOpened ? '-' : '+'}
                    </span>
                      <span>{messages('basic-5.key44')/*功能权限*/}</span>
                    </div>
                    {
                      appMenuList && appMenuList.length ?
                        <Tree
                          showLine
                          onExpand={this.onExpandRole}
                          expandedKeys={expandedKeysRole}
                          autoExpandParent={autoExpandParentRole}
                          onSelect={(selectedKeys, info) => this.onSelectRole(selectedKeys, info, 'app')}
                          selectedKeys={selectedKeysRole}
                        >
                          {this.renderTreeNode(searchValue && isSearching ? appMenuListCopy : appMenuList, 'app')}
                        </Tree>
                        : null
                    }
                  </div>

                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}

RoleMenuSettingNew.contextTypes = {
  router: React.PropTypes.object
};

function mapStateToProps (state) {
  return {
    organization: state.budget.organization,
    company: state.login.company,
    language: state.main.language,
    tenantMode: state.main.tenantMode
  };
}

export default connect(mapStateToProps)(RoleMenuSettingNew);
